/**
 * 取得缩放指定倍数后的坐标
 * @param  {[object]} params    rect
 * @param {number}  baseIndex 基点索引
 */
function getScaledRect(params, baseIndex) {
  const { x, y, width, height, scale } = params
  const offset = {
    x: 0,
    y: 0
  }
  const deltaXScale = scale.x - 1
  const deltaYScale = scale.y - 1
  const deltaWidth = width * deltaXScale
  const deltaHeight = height * deltaYScale
  const newWidth = width + deltaWidth
  const newHeight = height + deltaHeight
  const newX = x - deltaWidth / 2
  const newY = y - deltaHeight / 2
  if (baseIndex >= 0) {
    const points = [
      { x, y },
      { x: x + width / 2, y },
      { x: x + width, y },
      { x: x + width, y: y + height / 2 },
      { x: x + width, y: y + height },
      { x: x + width / 2, y: y + height },
      { x, y: y + height },
      { x, y: y + height / 2 }]
    const newPoints = [
      { x: newX, y: newY },
      { x: newX + newWidth / 2, y: newY },
      { x: newX + newWidth, y: newY },
      { x: newX + newWidth, y: newY + newHeight / 2 },
      { x: newX + newWidth, y: newY + newHeight },
      { x: newX + newWidth / 2, y: newY + newHeight },
      { x: newX, y: newY + newHeight },
      { x: newX, y: newY + newHeight / 2 }]
    offset.x = points[baseIndex].x - newPoints[baseIndex].x
    offset.y = points[baseIndex].y - newPoints[baseIndex].y
  }
  return {
    x: newX + offset.x,
    y: newY + offset.y,
    width: newWidth,
    height: newHeight
  }
}

/**
 * 获取旋转指定角度后的rect
 * @param  {[type]} options rect
 * @param  {[type]} angle   旋转角度
 * @return {[type]}
 */
function transform(options, angle) {
  const x = options.x
  const y = options.y
  const width = options.width
  const height = options.height

  const r = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)) / 2
  const a = Math.round(Math.atan(height / width) * 180 / Math.PI)
  const tlbra = 180 - angle - a
  const trbla = a - angle
  const ta = 90 - angle
  const ra = angle

  const halfWidth = width / 2
  const halfHeight = height / 2

  const middleX = x + halfWidth
  const middleY = y + halfHeight

  const topLeft = {
    x: middleX + r * Math.cos(tlbra * Math.PI / 180),
    y: middleY - r * Math.sin(tlbra * Math.PI / 180)
  }
  const top = {
    x: middleX + halfHeight * Math.cos(ta * Math.PI / 180),
    y: middleY - halfHeight * Math.sin(ta * Math.PI / 180)
  }
  const topRight = {
    x: middleX + r * Math.cos(trbla * Math.PI / 180),
    y: middleY - r * Math.sin(trbla * Math.PI / 180)
  }
  const right = {
    x: middleX + halfWidth * Math.cos(ra * Math.PI / 180),
    y: middleY + halfWidth * Math.sin(ra * Math.PI / 180)
  }
  const bottomRight = {
    x: middleX - r * Math.cos(tlbra * Math.PI / 180),
    y: middleY + r * Math.sin(tlbra * Math.PI / 180)
  }
  const bottom = {
    x: middleX - halfHeight * Math.sin(ra * Math.PI / 180),
    y: middleY + halfHeight * Math.cos(ra * Math.PI / 180)
  }
  const bottomLeft = {
    x: middleX - r * Math.cos(trbla * Math.PI / 180),
    y: middleY + r * Math.sin(trbla * Math.PI / 180)
  }
  const left = {
    x: middleX - halfWidth * Math.cos(ra * Math.PI / 180),
    y: middleY - halfWidth * Math.sin(ra * Math.PI / 180)
  }
  const minX = Math.min(topLeft.x, topRight.x, bottomRight.x, bottomLeft.x)
  const maxX = Math.max(topLeft.x, topRight.x, bottomRight.x, bottomLeft.x)
  const minY = Math.min(topLeft.y, topRight.y, bottomRight.y, bottomLeft.y)
  const maxY = Math.max(topLeft.y, topRight.y, bottomRight.y, bottomLeft.y)
  return {
    point: [topLeft, top, topRight, right, bottomRight, bottom, bottomLeft, left],
    width: maxX - minX,
    height: maxY - minY,
    left: minX,
    right: maxX,
    top: minY,
    bottom: maxY
  }
}

/**
 * 获取当前点和对角点
 * */
function getPointAndOpposite(point, pointDom, getPointList = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w']) {
  const currentIndex = getPointList.indexOf(pointDom)
  const oppositeIndex = currentIndex + 4 >= 8 ? currentIndex - 4 : currentIndex + 4
  return {
    current: {
      index: currentIndex,
      point: point[currentIndex]
    },
    opposite: {
      index: oppositeIndex,
      point: point[oppositeIndex]
    }
  }
}

/**
 * 获取新的矩形
 * */
function getNewRect(oPoint, scale, oTransformedRect, baseIndex) {
  const scaledRect = getScaledRect({
    x: oPoint.x,
    y: oPoint.y,
    width: oPoint.width,
    height: oPoint.height,
    scale: scale
  })
  const transformedRotateRect = transform(scaledRect, oPoint.rotate)
  // 计算到平移后的新坐标
  const translatedX = oTransformedRect.point[baseIndex].x - transformedRotateRect.point[baseIndex].x + transformedRotateRect.left
  const translatedY = oTransformedRect.point[baseIndex].y - transformedRotateRect.point[baseIndex].y + transformedRotateRect.top

  // 计算平移后元素左上角的坐标
  const newX = translatedX + transformedRotateRect.width / 2 - scaledRect.width / 2
  const newY = translatedY + transformedRotateRect.height / 2 - scaledRect.height / 2

  // 缩放后元素的高宽
  const newWidth = scaledRect.width
  const newHeight = scaledRect.height

  return {
    x: newX,
    y: newY,
    width: newWidth,
    height: newHeight
  }
}

/**
 * 获取绕某点旋转后的新点
 * */
function getRotate(point, center, rotate) {
  const deg = Math.PI / 180 * rotate
  const newX = center.x + (point.x - center.x) * Math.cos(deg) - (point.y - center.y) * Math.sin(deg)
  const newY = center.y + (point.x - center.x) * Math.sin(deg) + (point.y - center.y) * Math.cos(deg)
  return {
    x: newX,
    y: newY
  }
}

export default {
  getScaledRect,
  transform,
  getPointAndOpposite,
  getNewRect,
  getRotate
}
